/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package core.net;

import core.pojos.DriveItem;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.scribe.model.Token;

/**
 *
 * @author Royal
 */
public class DriveRequest {

    private final static String ROOT_META = "https://www.googleapis.com/drive/v2/files";
    private final static String MAX_RESULTS = "maxResults";
    private final static String MAX_RESULTS_VALUE = "1000";
    private final static String FILTER = "q";
    private final static String FILTER_FORMAT = "'me' in owners and '%s' in parents";
    private final static String FIELDS = "fields";
    private final static String FIELDS_VALUE = "items(downloadUrl,fileExtension,fileSize,id,mimeType,modifiedDate,originalFilename,title)";
    private final static String FIELDS_VALUE_UPLOAD = "fileExtension,id,mimeType,parents,title";
    private final static String FIELDS_VALUE_DOWNLOAD = "downloadUrl";
    private final static String ROOT_FOLDER = "root";
    private static final String ROOT_PUT = "https://www.googleapis.com/upload/drive/v2/files";

    // access token
    private final Token token;

    public DriveRequest(Token token) {
        this.token = token;
    }

    /**
     * Retrieves file and folder metadata
     *
     * @param path The relative path to the file or folder
     * @return JSON String
     * @throws URISyntaxException Invalid URI
     * @throws IOException Bad request
     */
    public String list(String path) throws URISyntaxException, IOException {

        if (path == null || path.trim().length() == 0) {
            path = ROOT_FOLDER;
        }
        URI uri = Param.create()
                .setToken(token)
                .setUrl(ROOT_META)
                .setParam(MAX_RESULTS, MAX_RESULTS_VALUE)
                .setParam(FILTER, String.format(FILTER_FORMAT, path))
                .setParam(FIELDS, FIELDS_VALUE)
                .buildURI();
        return Request.Get(uri)
                .execute()
                .returnContent().asString();
    }

    /**
     * Downloads a file
     *
     * @param path The relative path to the file you want to retrieve
     * @param out Output stream to write downloaded file
     * @throws URISyntaxException
     * @throws IOException
     */
    public String download(String path) throws URISyntaxException, IOException {

        URI uri = Param.create()
                .setToken(token)
                .setUrl(combine(ROOT_META, path))
                .setParam(FIELDS, FIELDS_VALUE_DOWNLOAD)
                .buildURI();
        String strurl = Request.Get(uri)
                .execute()
                .returnContent().asString();
        strurl = strurl.replace("{\n" + " \"downloadUrl\": \"", "");
        strurl = strurl.replace("&e=download&gd=true\"\n" + "}", "");
        return strurl;
    }

    /**
     * Uploads a file
     *
     * @param path The full path to the file you want to write to
     * @param file The upload file
     * @return JSON String
     * @throws URISyntaxException
     * @throws IOException
     */
    public String uploadContent(String mimeType, File file) throws IOException, URISyntaxException {
        URI uri = Param.create()
                .setToken(token)
                .setUrl(ROOT_PUT)
                .setParam("uploadType", "media")
                .setParam(FIELDS, FIELDS_VALUE_UPLOAD)
                .buildURI();
        return Request.Post(uri)
                .bodyFile(file, ContentType.APPLICATION_OCTET_STREAM)
                .addHeader("X-Upload-Content-Type", mimeType)
                .execute()
                .returnContent().asString();
    }

    public String upload(String mimeType, String title, String fileExtension, File file) throws IOException, URISyntaxException {
        String json = uploadContent("application/octet-stream", file);
        DriveItem di = Json.ToDriveItemList(json);
        URI uri = Param.create()
                .setToken(token)
                .setUrl(combine(ROOT_META, di.id))
                .setParam(FIELDS, FIELDS_VALUE_UPLOAD)
                .buildURI();
        return Request.Put(uri)
                .bodyString("{\n" + " \"title\": \"" + title + "\",\n" + " \"fileExtension\": \"" + fileExtension + "\",\n" + " \"mimeType\": \"" + mimeType + "\"\n" + "}", ContentType.APPLICATION_JSON)
                .execute()
                .returnContent().asString();
    }

    private String combine(String root, String path) {
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        return root + path;
    }

    public void delete(String path) throws URISyntaxException, IOException {
        URI uri = Param.create()
                .setToken(token)
                .setUrl(combine(ROOT_META, path))
                .buildURI();
        Request.Delete(uri)
                .execute()
                .returnContent().asString();

    }

    public String createfolder(String title, String parentsid) throws IOException, URISyntaxException {
        URI uri = Param.create()
                .setToken(token)
                .setUrl(ROOT_META)
                .buildURI();
        return Request.Post(uri)
                .bodyString("{\n" + " \"title\": \"" + title + "\",\n" + " \"mimeType\": \"application/vnd.google-apps.folder\",\n" + " \"parents\": [\n" + "  {\n" + "   \"id\": \"" + parentsid + "\"\n" + "  }\n" + " ]\n" + "}", ContentType.APPLICATION_JSON)
                .execute()
                .returnContent().asString();
    }

    public String rename(String title, String fileExtension, String FileID) throws IOException, URISyntaxException {
        URI uri = Param.create()
                .setToken(token)
                .setUrl(ROOT_META + "/" + FileID)
                .setParam(FIELDS, FIELDS_VALUE_UPLOAD)
                .buildURI();
        return Request.Put(uri)
                .bodyString("{\n" + " \"title\": \"" + title + "\",\n" + " \"fileExtension\": \"" + fileExtension + "\"\n" + "}", ContentType.APPLICATION_JSON)
                .execute()
                .returnContent().asString();

    }

    public String movefile(String FileID, String FolderID) throws IOException, URISyntaxException {
        URI uri = Param.create()
                .setToken(token)
                .setUrl("https://www.googleapis.com/drive/v2/files/" + FileID + "/parents")
                .buildURI();
        String move = Request.Post(uri)
                .bodyString("{\n" + " \"id\": \"" + FolderID + "\"\n" + "}", ContentType.APPLICATION_JSON)
                .execute()
                .returnContent().asString();
        System.out.println(move);
        return move;

    }
}
